<route lang="json5">
{
  layout: 'default',
  style: {
    navigationBarTitleText: '实验报告单',
    enablePullDownRefresh: false,
    navigationStyle: 'custom',
  },
}
</route>

<template>
  <page-meta :root-font-size="setting.rootFontSize"></page-meta>
  <view style="display: flex; flex-direction: column; height: 100vh; background-color: #f2f2f1">
    <view style="position: sticky; top: 0; z-index: 9999">
      <wd-navbar
        :title="`${assayType === 'qcMiddleReport' ? '实验检验报告' : '任务检验报告'}`"
        :bordered="false"
        safeAreaInsetTop
      >
        <template #left>
          <wd-icon name="thin-arrow-left" size="22px" color="white" @click="goBack"></wd-icon>
        </template>
      </wd-navbar>
    </view>
    <view class="actions-bar">
      <th-button
        size="small"
        class="btn"
        type="text"
        v-if="checkPremiss(`qc_${assayType}_edit`)"
        :disabled="![0, 3].includes(form.status) || form.taskAllStatus !== '1'"
        @click="onSave"
      >
        保存
      </th-button>
      <th-button
        size="small"
        class="btn"
        type="text"
        v-if="checkPremiss(`qc_${assayType}_submit`)"
        :disabled="!form.id || ![0, 3].includes(form.status) || form.taskAllStatus !== '1'"
        @click="onSubmit"
      >
        提交
      </th-button>
      <th-button
        size="small"
        class="btn"
        type="text"
        v-if="checkPremiss(`qc_${assayType}_revoke`)"
        :disabled="!form.id || form.status !== 1 || form.taskAllStatus !== '1'"
        @click="handleShow('revoke')"
      >
        撤回
      </th-button>
      <th-button
        size="small"
        class="btn"
        type="text"
        v-if="checkPremiss(`qc_${assayType}_revive`)"
        :disabled="!form.id || form.status !== 2 || form.taskAllStatus !== '1'"
        @click="handleShow('revive')"
      >
        弃审
      </th-button>
      <block v-if="form.status === 1 && checkPremiss(`qc_${assayType}_check`)">
        <th-button
          v-if="form.instanceId"
          :disabled="!form.taskId || form.taskAllStatus !== '1'"
          type="text"
          @click="handleShow('complete')"
          size="small"
        >
          审核
        </th-button>
        <th-button v-else type="text" @click="onComplete(2)" :disabled="form.taskAllStatus !== '1'">
          审核
        </th-button>
      </block>
    </view>
    <view style="display: flex; flex: 1; flex-direction: column; height: 0">
      <view style="flex: 1; overflow: auto">
        <th-card title="基础信息">
          <th-form>
            <th-form-item label="报告单号">
              <view class="text seq-no-text">
                {{ form.reportCode }}
              </view>
            </th-form-item>
            <th-form-item label="报检单号">
              <view class="text seq-no-text">
                {{ form.checkCode }}
              </view>
            </th-form-item>
            <th-form-item label="日期">
              <view v-if="[0, 3].includes(form.status)" class="text seq-no-text">
                <th-datetime-picker
                  v-model:value="form.reportDate"
                  format="YYYY-MM-DD"
                  placeholder="请选择日期"
                ></th-datetime-picker>
              </view>
              <text v-else>{{ form.reportDate }}</text>
            </th-form-item>
            <th-form-item label="报检人">
              <view class="text seq-no-text">
                {{ form.inspectName }}
              </view>
            </th-form-item>
            <th-form-item label="任务编码">
              <view class="text seq-no-text">
                {{ form.taskCode }}
              </view>
            </th-form-item>
            <th-form-item label="产品名称">
              <view class="text seq-no-text">
                {{ form.invName }}
              </view>
            </th-form-item>
            <th-form-item label="产品规格">
              <view class="text seq-no-text">
                {{ form.invStd }}
              </view>
            </th-form-item>

            <th-form-item v-if="assayType === 'qcMiddleReport'" label="检验类型">
              <view class="text seq-no-text">
                {{ form.type === 0 ? '中控' : '终检' }}
              </view>
            </th-form-item>
            <block v-if="assayType === 'qcMiddleReport'">
              <th-form-item label="取样时间">
                <view class="text seq-no-text">{{ form.sampleTime }}</view>
              </th-form-item>

              <th-form-item label="取样位置">
                <view class="text seq-no-text">{{ form.position }}</view>
              </th-form-item>

              <th-form-item label="取样工序">
                <view class="text seq-no-text">
                  {{ form.processName }}
                </view>
              </th-form-item>
            </block>
            <th-form-item v-if="assayType === 'qcMiddleReport'" label="样品批号">
              <view class="text seq-no-text">
                {{ form.sampleBatch }}
              </view>
            </th-form-item>
            <th-form-item v-else label="样品编码">
              <view class="text seq-no-text">
                {{ form.sampleCode }}
              </view>
            </th-form-item>

            <th-form-item label="单据状态">
              <view class="text seq-no-text">
                <wd-tag
                  :bg-color="getStatus(form.status)['color']"
                  :color="getStatus(form.status)['color']"
                  plain
                >
                  {{ getStatus(form.status)['label'] }}
                </wd-tag>
              </view>
            </th-form-item>
          </th-form>
        </th-card>
        <th-card title="检测项目">
          <reportTable
            :data="form.qcMiddleReportsList || form.qcExoticReportsList"
            :mode="`${[0, 3].includes(form.status) ? 'form' : 'detail'}`"
            ref="reportRef"
            :reportCode="form.reportCode"
            :cus-flag="form.cusFlag"
          ></reportTable>
        </th-card>

        <th-card
          title="审核信息"
          v-if="form.status == '1' || form.status == '2' || form.status == '3'"
        >
          <view class="row-list">
            <view>
              <flowTable ref="flowDetailsTableRef" :processInstanceId="form.instanceId"></flowTable>
            </view>
          </view>
        </th-card>
      </view>
    </view>
  </view>
  <th-dialog v-model:visible="commentShow">
    <template v-slot:content>
      <th-input
        v-model:value="comment"
        mode="textarea"
        autoheight
        placeholder="请填写原因"
        style="padding: 10rpx 0"
      ></th-input>
    </template>
    <template v-slot:footer>
      <view class="btn_group">
        <view class="btn" @click="handleClose">取消</view>
        <view class="btn" style="color: #409eff" v-if="action === 'revoke'" @click="onRevoke">
          撤回
        </view>
        <view class="btn" style="color: #409eff" v-if="action === 'revive'" @click="onRevive">
          弃审
        </view>
        <view class="btn" style="color: #f50" v-if="action === 'complete'" @click="onComplete(3)">
          拒绝
        </view>
        <view
          class="btn"
          style="color: #409eff"
          v-if="action === 'complete'"
          @click="onComplete(2)"
        >
          同意
        </view>
      </view>
    </template>
  </th-dialog>
</template>

<script lang="ts" setup>
import { useSetting } from '@/stores/setting';
import {
  retInfoBarCode,
  analysisList,
  reportSave,
  reportUpdate,
  reportInfo,
  reportSubmit,
  reportRevoke,
  reportRevive,
  reportComplete,
} from '@/service/pm-assay';
import { formatByDayjs } from '@/utils/util';
import { useUserStore } from '@/stores/user';
import { useDict } from '@/hooks/dict';
import thInput from './component/th-input.vue';
import thButton from './component/th-button.vue';
import thDialog from './component/th-dialog.vue';
import reportTable from './component/reportTable.vue';
import thDatetimePicker from './component/th-datetime-picker.vue';
import showModal from '@/utils/modal';

const assayType = ref();
const assayKey = ref();
const setting = useSetting();
const emits = defineEmits(['refresh']);
const userStore = useUserStore();
const flowDetailsTableRef: any = ref({});

// 提交表单数据
const form = ref({
  id: '',
  pid: '', // 报检单id
  reportCode: '',
  checkCode: '',
  reportDate: formatByDayjs(new Date(), 'YYYY-MM-DD'),
  inspectName: '',
  taskCode: '',
  sampleBatch: '',
  sampleCode: '',
  invName: '',
  invStd: '',
  position: '',
  processName: '',
  sampleTime: formatByDayjs(new Date(), 'YYYY-MM-DD HH:mm:ss'),
  type: 0,
  status: undefined,
  taskId: '',
  instanceId: '',
  cusFlag: undefined,
  taskAllStatus: undefined,

  qcMiddleReportsList: undefined,
  qcExoticReportsList: undefined,
});

const fillInfo = (res) => {
  const {
    reportCode,
    checkCode,
    inspectName,
    taskCode,
    sampleBatch,
    sampleCode,
    position,
    processName,
    sampleTime,
    invName,
    status,
    invStd,
    type,
    cusFlag,
    taskAllStatus,
    qcMiddleChecksList,
    qcExoticChecksList,
    qcMiddleReportsList,
    qcExoticReportsList,
  } = res.data;
  form.value.reportCode = reportCode;
  form.value.checkCode = checkCode;
  form.value.inspectName = inspectName;
  form.value.taskCode = taskCode;
  form.value.sampleBatch = sampleBatch;
  form.value.sampleCode = sampleCode;
  form.value.position = position;
  form.value.processName = processName;
  form.value.sampleTime = sampleTime;
  form.value.invName = invName;
  form.value.invStd = invStd;
  form.value.type = type;
  form.value.status = status;
  form.value.cusFlag = cusFlag;
  form.value.taskAllStatus = taskAllStatus;

  // 通过id查到的详情
  if (qcMiddleReportsList || qcExoticReportsList) {
    if (qcMiddleReportsList) {
      form.value.qcMiddleReportsList = qcMiddleReportsList;
    } else {
      form.value.qcExoticReportsList = qcExoticReportsList;
    }
  } else {
    const map = {};
    (qcMiddleChecksList || qcExoticChecksList).forEach((item) => {
      if (!map[item.analysisId]) {
        const { id, pid, analysisId, analysisName, indexEntities, equipmentEntities, itemDTOS } =
          item;
        const obj = {
          id,
          pid,
          analysisId,
          analysisName,
          indexEntities,
          equipmentEntities,
          itemDTOS,
        };
        map[item.analysisId] = { ...obj };
      }
    });

    form.value[assayKey.value] = Object.keys(map).map((key) => {
      return map[key];
    });
  }
};

const init = (id) => {
  uni.showLoading({
    mask: true,
  });

  reportInfo(assayType.value, { id })
    .then((res) => {
      const { id, pid, taskId, instanceId, reportDate } = res.data;
      form.value.id = id;
      form.value.pid = pid;
      form.value.taskId = taskId;
      form.value.instanceId = instanceId;
      form.value.reportDate = reportDate;
      fillInfo(res);
    })
    .finally(() => {
      uni.hideLoading();
    });
};

const analysisOptions = ref([]);

onLoad(async (options) => {
  const { id, checkCode, t } = options;

  assayType.value = t;
  assayKey.value = t === 'qcMiddleReport' ? 'qcMiddleReportsList' : 'qcExoticReportsList';
  // 新增
  if (checkCode) {
    retInfoBarCode(
      assayType.value === 'qcMiddleReport' ? 'qcMiddleCheck' : 'qcExoticCheck',
      checkCode,
    ).then((res) => {
      form.value.pid = res.data.id;
      form.value.checkCode = checkCode;
      fillInfo(res);
    });
  } else {
    init(id);
  }

  // 获取分析手段
  await analysisList({ size: 20000 }).then((res) => {
    analysisOptions.value = res.data.records.map((item) => {
      const { analysisName, id, equipmentList, analysisIndexUnit, analysisIndexList } = item;
      return {
        label: analysisName,
        value: id,
        equipmentList,
        analysisIndexUnit,
        analysisIndexList,
      };
    });
  });
});

const checkPremiss = (k) => {
  return userStore.userInfos.authBtnList.some((v: string) => v === k);
};

const goBack = () => {
  uni.navigateBack();
};

const reportRef = ref();
const onSave = (ref) => {
  const formData = { ...form.value };
  const { delQueue, tableList } = reportRef.value.getTableList();
  tableList.forEach((row) => {
    if (row.attachmentsDTOS && row.attachmentsDTOS.length) {
      row.attachmentsDTOS = row.attachmentsDTOS.filter((item) => !delQueue.includes(item.id));
    }
  });
  // 修改
  if (formData.id) {
    const reportsList = {};
    tableList.forEach((row: any) => {
      const {
        unit,
        id,
        pid,
        topId,
        topPid,
        analysisName,
        analysisId,
        remark,
        itemName,
        itemValue,
        valueType,
        equipmentCode,
        assayerName,
        assayerCode,
        equipmentName,
        itemCode,
        standardValuePm,
    		standardValue,
        attachmentsDTOS,
      } = row;
      if (!reportsList[row.analysisId]) {
        const tempObj = {
          id: topId,
          pid: topPid,
          analysisName,
          analysisId,
          itemDTOS: [],
        };
        tempObj.itemDTOS = [
          {
            id,
            pid,
            unit,
            equipmentCode,
            equipmentName,
            itemName,
            itemCode,
            valueType,
            itemValue,
            assayerName,
            assayerCode,
            remark,
            standardValuePm,
	      		standardValue,
            attachmentsDTOS: attachmentsDTOS || [],
          },
        ];
        reportsList[row.analysisId] = tempObj;
      } else {
        reportsList[row.analysisId].itemDTOS.push({
          id,
          pid,
          unit,
          equipmentCode,
          equipmentName,
          remark,
          itemName,
          itemCode,
          valueType,
          itemValue,
          assayerName,
          assayerCode,
          standardValuePm,
		      standardValue,
          attachmentsDTOS: attachmentsDTOS || [],
        });
      }
    });
    formData[assayKey.value] = Object.keys(reportsList).map((key) => {
      return reportsList[key];
    });
  } else {
    // 新增
    const reportsList = {};
    tableList.forEach((row: any) => {
      const {
        unit,
        analysisName,
        analysisId,
        remark,
        itemName,
        valueType,
        itemValue,
        equipmentCode,
        assayerName,
        assayerCode,
        equipmentName,
        itemCode,
        standardValuePm,
		    standardValue,
        attachmentsDTOS,
      } = row;
      if (!reportsList[row.analysisId]) {
        const tempObj = {
          pid: formData.pid,
          analysisName,
          analysisId,
          itemDTOS: [],
        };
        tempObj.itemDTOS = [
          {
            unit,
            equipmentCode,
            equipmentName,
            itemName,
            itemCode,
            valueType,
            itemValue,
            assayerName,
            assayerCode,
            remark,
            standardValuePm,
		      	standardValue,
            attachmentsDTOS: attachmentsDTOS || [],
          },
        ];
        reportsList[row.analysisId] = tempObj;
      } else {
        reportsList[row.analysisId].itemDTOS.push({
          unit,
          equipmentCode,
          equipmentName,
          remark,
          itemName,
          itemCode,
          valueType,
          itemValue,
          assayerName,
          assayerCode,
          standardValuePm,
    		  standardValue,
          attachmentsDTOS: attachmentsDTOS || [],
        });
      }
    });
    formData[assayKey.value] = Object.keys(reportsList).map((key) => {
      return reportsList[key];
    });
  }
  if (ref !== 'submit') {
    uni.showLoading({
      title: '保存中',
      mask: true,
    });
  }

  (form.value.id ? reportUpdate(assayType.value, formData) : reportSave(assayType.value, formData))
    .then((res) => {
      if (res.code === 0) {
        if (ref !== 'submit') {
          uni.showToast({
            mask: true,
            title: `保存成功`,
            icon: 'none',
          });
          uni.$emit('assayReportRefresh', true);
          init(res.data.id);
        } else {
          onSubmit();
        }
      } else {
        uni.showToast({
          mask: true,
          title: `保存失败，失败原因${res.msg}`,
          icon: 'none',
        });
      }
    })
    .finally(() => {
      commentShow.value = false;
      comment.value = '';
      uni.hideLoading();
    });
};

// 刷新流转详情
const refreshFlow = () => {
  if (form.value.instanceId) {
    nextTick(() => {
      flowDetailsTableRef.value.getFlowDetails();
    });
  }
};

// 提交
const reportSubmitHandle = () => {
  setTimeout(() => {
    uni.showLoading({
      title: '提交中',
      mask: true,
    });
    reportSubmit(assayType.value, { id: form.value.id })
      .then((res) => {
        if (res.code === 0) {
          uni.showToast({
            mask: true,
            title: `单据${form.value.reportCode}提交成功`,
            icon: 'none',
          });
          uni.$emit('assayReportRefresh', true);
          init(form.value.id);
          refreshFlow();
        } else {
          uni.showToast({
            mask: true,
            title: `单据${form.value.reportCode}提交失败，失败原因：${res.msg}`,
            icon: 'none',
          });
        }
      })
      .finally(() => {
        commentShow.value = false;
        comment.value = '';
        uni.hideLoading();
      });
  });
};
// 提交
const onSubmit = (e?: any) => {
  if (e) {
    showModal({
      title: '提示',
      content: '是否提交该单据',
      showCancel: true,
      confirm: () => {
        // 编辑模式 提交前先保存
        if (e) {
          onSave('submit');
          return;
        }
        uni.showLoading({
          title: '提交中',
          mask: true,
        });
        reportSubmitHandle();
      },
    });
  } else {
    // 保存后回调 不弹窗
    reportSubmitHandle();
  }
};

// 撤回
const comment = ref('');
const action = ref('');
const commentShow = ref(false);
const handleClose = () => {
  comment.value = '';
  commentShow.value = false;
};
const handleShow = (type) => {
  action.value = type;
  commentShow.value = true;
};
const onRevoke = () => {
  showModal({
    title: '提示',
    content: '是否撤回该单据',
    showCancel: true,
    confirm: () => {
      uni.showLoading({
        title: '撤回中',
        mask: true,
      });
      reportRevoke(assayType.value, {
        id: form.value.id,
        instanceId: form.value.instanceId,
        comment: comment.value,
      })
        .then((res) => {
          if (res.code === 0) {
            uni.showToast({
              mask: true,
              title: `单据${form.value.reportCode}撤回成功`,
              icon: 'none',
            });
            handleClose();
            uni.$emit('assayReportRefresh', true);
            init(form.value.id);
            refreshFlow();
          } else {
            uni.showToast({
              mask: true,
              title: `单据${form.value.reportCode}撤回失败，失败原因：${res.msg}`,
              icon: 'none',
            });
          }
        })
        .finally(() => {
          commentShow.value = false;
          comment.value = '';
          uni.hideLoading();
        });
    },
  });
};

// 弃审
const onRevive = () => {
  showModal({
    title: '提示',
    content: '是否弃审该单据',
    showCancel: true,
    confirm: () => {
      uni.showLoading({
        title: '弃审中',
        mask: true,
      });
      reportRevive(assayType.value, {
        id: form.value.id,
        comment: comment.value,
      })
        .then((res) => {
          if (res.code === 0) {
            uni.showToast({
              mask: true,
              title: `单据${form.value.reportCode}弃审成功`,
              icon: 'none',
            });
            handleClose();
            uni.$emit('assayReportRefresh', true);
            init(form.value.id);
            refreshFlow();
          } else {
            uni.showToast({
              mask: true,
              title: `单据${form.value.reportCode}弃审失败，失败原因：${res.msg}`,
              icon: 'none',
            });
          }
        })
        .finally(() => {
          commentShow.value = false;
          comment.value = '';
          uni.hideLoading();
        });
    },
  });
};

// 审核
const onComplete = (status: number) => {
  if (status === 3 && !comment.value) {
    uni.showToast({
      title: '请填写审核意见',
      icon: 'none',
      mask: true,
    });
    return;
  }

  const params = {
    taskId: form.value.taskId,
    comment: comment.value,
    id: form.value.id,
    status,
  };
  uni.showLoading({
    title: '审核中',
    mask: true,
  });
  reportComplete(assayType.value, params)
    .then((res) => {
      if (res.code === 0) {
        uni.showToast({
          title: '单据审核成功',
          icon: 'none',
          mask: true,
        });
        handleClose();
        init(form.value.id);
        uni.$emit('assayReportRefresh', true);
        refreshFlow();
      } else {
        uni.showToast({
          mask: true,
          title: `单据审核失败，失败原因：${res.msg}`,
          icon: 'none',
        });
      }
    })
    .finally(() => {
      commentShow.value = false;
      comment.value = '';
      uni.hideLoading();
    });
};

const statusList = [
  {
    text: '未提交',
    value: '0',
    color: '#108ee9',
  },
  {
    text: '审批中',
    value: '1',
    color: '#d46b08',
  },
  {
    text: '已审核',
    value: '2',
    color: '#87d068',
  },
  {
    text: '驳回',
    value: '3',
    color: '#f50',
  },
  {
    text: '撤回',
    value: '9',
    color: '#f50',
  },
];

const { bill_status } = useDict('bill_status');
const getStatus = (status) => {
  if (status == null)
    return {
      text: '未提交',
      value: 0,
      color: '#108ee9',
    };
  const o1 = statusList.find((item) => item.value == status);
  const o = bill_status.value.find((item) => item.value == status);
  return o
    ? {
        ...o,
        color: o1.color,
      }
    : { text: status };
};
</script>

<style lang="scss" scoped>
@import '../experiment/components/table';

.actions-bar {
  background: #fff;
  padding: 8rpx 15rpx;
  border-bottom: 1rpx solid #dedede;
  .btn {
    border: none;
  }
  text {
    color: #dedede;
    font-size: 24rpx;
  }
}

.seq-no-text {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  word-break: break-all;
  word-wrap: break-word;
}

.btn_group {
  display: flex;
  justify-content: space-between;
  border-top: 1rpx solid #f1f1f1;
  .btn {
    flex: 1;
    line-height: 40px;
    padding: 10rpx 0;
    text-align: center;
    color: black;
    border-left: 1px solid #f1f1f1;
  }

  .danger {
    background-color: #f56c6c;
  }

  .primary {
    background-color: #409eff;
  }
}

.form-demandDesc {
  align-items: flex-start !important;
}
</style>
